﻿using Grand.Business.Core.Extensions;
using Grand.Business.Core.Interfaces.Catalog.Prices;
using Grand.Business.Core.Interfaces.Catalog.Products;
using Grand.Business.Core.Interfaces.Catalog.Tax;
using Grand.Business.Core.Interfaces.Common.Localization;
using Grand.Business.Core.Interfaces.Storage;
using Grand.Domain.Catalog;
using Grand.Domain.Common;
using Grand.Domain.Media;
using Grand.Domain.Orders;
using Grand.Web.Extensions;
using Grand.Web.Features.Models.ShoppingCart;
using Grand.Web.Models.Media;
using Grand.Web.Models.ShoppingCart;
using MediatR;
using Microsoft.AspNetCore.Routing;

namespace Grand.Web.Features.Handlers.ShoppingCart;

public class GetMiniWishlistHandler : IRequestHandler<GetMiniWishlist, MiniWishlistModel>
{
    private readonly LinkGenerator _linkGenerator;
    private readonly MediaSettings _mediaSettings;
    private readonly IPictureService _pictureService;
    private readonly IPriceFormatter _priceFormatter;
    private readonly IPricingService _pricingService;
    private readonly IProductAttributeFormatter _productAttributeFormatter;
    private readonly IProductService _productService;
    private readonly ShoppingCartSettings _shoppingCartSettings;
    private readonly ITaxService _taxService;
    private readonly ITranslationService _translationService;

    public GetMiniWishlistHandler(
        IProductService productService,
        IProductAttributeFormatter productAttributeFormatter,
        ITranslationService translationService,
        ITaxService taxService,
        IPricingService priceCalculationService,
        IPriceFormatter priceFormatter,
        IPictureService pictureService,
        LinkGenerator linkGenerator,
        ShoppingCartSettings shoppingCartSettings,
        MediaSettings mediaSettings)
    {
        _productService = productService;
        _productAttributeFormatter = productAttributeFormatter;
        _translationService = translationService;
        _taxService = taxService;
        _pricingService = priceCalculationService;
        _priceFormatter = priceFormatter;
        _pictureService = pictureService;
        _linkGenerator = linkGenerator;
        _shoppingCartSettings = shoppingCartSettings;
        _mediaSettings = mediaSettings;
    }

    public async Task<MiniWishlistModel> Handle(GetMiniWishlist request, CancellationToken cancellationToken)
    {
        var model = new MiniWishlistModel {
            EmailWishlistEnabled = _shoppingCartSettings.EmailWishlistEnabled,
            ShowProductImages = _shoppingCartSettings.ShowProductImagesOnWishList,
            TotalProducts = request.Cart.Count
        };

        if (!request.Cart.Any())
            return model;

        #region Cart items

        foreach (var sci in request.Cart)
        {
            var product = await _productService.GetProductById(sci.ProductId);
            if (product == null)
                continue;

            var sename = product.GetSeName(request.Language.Id);
            var cartItemModel = new MiniWishlistModel.WishlistItemModel {
                Id = sci.Id,
                Sku = product.FormatSku(sci.Attributes),
                ProductId = product.Id,
                ProductName = product.GetTranslation(x => x.Name, request.Language.Id),
                ProductSeName = sename,
                ProductUrl = _linkGenerator.GetPathByRouteValues("Product", new { SeName = sename }),
                Quantity = sci.Quantity,
                AttributeInfo = await _productAttributeFormatter.FormatAttributes(product, sci.Attributes)
            };

            //unit prices
            if (product.CallForPrice)
            {
                cartItemModel.UnitPrice = _translationService.GetResource("Products.CallForPrice");
            }
            else
            {
                var productprice = await _taxService.GetProductPrice(product,
                    (await _pricingService.GetUnitPrice(sci, product)).unitprice);

                cartItemModel.UnitPrice = _priceFormatter.FormatPrice(productprice.productprice);
                cartItemModel.UnitPriceValue = productprice.productprice;
                cartItemModel.TaxRate = productprice.taxRate;
            }

            //picture
            if (_shoppingCartSettings.ShowProductImagesOnWishList)
                cartItemModel.Picture = await PrepareCartItemPicture(product, sci.Attributes);


            model.Items.Add(cartItemModel);
        }

        #endregion

        return model;
    }

    private async Task<PictureModel> PrepareCartItemPicture(
        Product product, IList<CustomAttribute> attributes)
    {
        var sciPicture = await product.GetProductPicture(attributes, _productService, _pictureService);
        return new PictureModel {
            Id = sciPicture?.Id,
            ImageUrl = await _pictureService.GetPictureUrl(sciPicture, _mediaSettings.MiniCartThumbPictureSize),
            Title = string.Format(_translationService.GetResource("Media.Product.ImageLinkTitleFormat"), product.Name),
            AlternateText = string.Format(_translationService.GetResource("Media.Product.ImageAlternateTextFormat"),
                product.Name)
        };
    }
}